﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.ApplicationModels;
using System.Linq;

namespace SharpSoft.Web
{
    public class AuthorizeProvider : Microsoft.AspNetCore.Mvc.ApplicationModels.IApplicationModelProvider
    {


        public int Order => -99;
        /// <summary>
        /// 提供一个处理程序用于保存权限映射表
        /// </summary>
        public Action<IDictionary<string, PermissionInfo>> SavePermissionMapHandler { get; set; }
        public Task<IEnumerable<IAuthorizationHandler>> GetHandlersAsync(AuthorizationHandlerContext context)
        {
            throw new NotImplementedException();
        }


        private static string GetArea(IReadOnlyList<object> atts)
        {
            var areas = atts.OfType<Microsoft.AspNetCore.Mvc.AreaAttribute>().ToArray();
            if (areas.Length > 0)
            {
                return areas[0].RouteValue;
            }
            return null;
        }
        private static SharpSoft.Web.PermissionAuthorizeAttribute GetAuthorize(IReadOnlyList<object> atts)
        {
            var auths = atts.OfType<SharpSoft.Web.PermissionAuthorizeAttribute>().ToArray();
            if (auths.Length > 0)
            {
                return auths[0];
            }
            return null;
        }
        /// <summary>
        /// 根据区域 控制器  活动 来创建一个唯一的权限名称
        /// </summary>
        /// <param name="area"></param>
        /// <param name="controller"></param>
        /// <param name="action"></param>
        /// <returns></returns>
        public static string CreatePermissionName(string area, string controller, string action, string extFlag)
        {
            string name = "";
            if (!string.IsNullOrEmpty(area))
            {
                name = $"{area}.{controller}.{action}";
            }
            else
            {
                name = $"{controller}.{action}";
            }
            if (!string.IsNullOrEmpty(extFlag))
            {
                name += $".{extFlag}";
            }
            return name.ToUpper();
        }
        /// <summary>
        /// 获取权限名称
        /// </summary>
        /// <param name="actionModel"></param>
        /// <returns></returns>
        public string CreatePermissionName(ActionModel actionModel)
        {
            string area = "";
            string controller = actionModel.Controller.ControllerName;
            string action = "";
            action = actionModel.ActionName;
            var authAction = GetAuthorize(actionModel.Attributes);
            if (authAction != null && authAction.CheckPermission)
            {  //在Action上定义了需要检查权限
                var areaD = GetArea(actionModel.Attributes);
                if (areaD != null)
                {
                    area = areaD;
                }
                PermissionInfo pi = new PermissionInfo();
                pi.Remark = authAction.Remark;
                pi.Path = authAction.Path;
                return CreatePermissionName(area, controller, action, authAction.ExtensionFlag);
            }
            return null;
        }

        public void OnProvidersExecuting(ApplicationModelProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (AppUser.PermissionMap == null)
            {//加载程序中预定义的权限清单
                Dictionary<string, PermissionInfo> pernames = new Dictionary<string, PermissionInfo>();
                foreach (var controllerModel in context.Result.Controllers)
                {
                    string area = "";
                    string controller = controllerModel.ControllerName;
                    string action = "";
                    var auth = GetAuthorize(controllerModel.Attributes);
                    if (auth != null && auth.CheckPermission)
                    {  //在Controller上定义了需要检查权限
                        var areaD = GetArea(controllerModel.Attributes);
                        if (areaD != null)
                        {
                            area = areaD;
                        }
                        PermissionInfo pi = new PermissionInfo();
                        pi.Remark = auth.Remark;
                        pi.Path = auth.Path;
                        pernames.Add(CreatePermissionName(area, controller, action, auth.ExtensionFlag), pi);
                    }
                    {//检查所有Action上的权限定义特性
                        foreach (var actionModel in controllerModel.Actions)
                        { 
                            action = actionModel.ActionName;
                            var authAction = GetAuthorize(actionModel.Attributes);
                            if (authAction != null && authAction.CheckPermission)
                            {  //在Action上定义了需要检查权限
                                var areaD = GetArea(actionModel.Attributes);
                                if (areaD != null)
                                {
                                    area = areaD;
                                }
                                PermissionInfo pi = new PermissionInfo();
                                pi.Remark = authAction.Remark;
                                pi.Path = authAction.Path;
                                pernames.Add(CreatePermissionName(area, controller, action, authAction.ExtensionFlag), pi);
                            }
                        }
                    }
                }
                if (this.SavePermissionMapHandler != null)
                {//持久储存权限清单，以便于与后续通过其他途径定义的权限进行混合
                    this.SavePermissionMapHandler(pernames);
                }
                AppUser.PermissionMap = new PermissionMap(pernames);
            }

        }
        public void OnProvidersExecuted(ApplicationModelProviderContext context)
        {
        }


    }
}
